﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="GridRunRepository.cs" company="DST Nexdox">
//   Copyright (c) DST Nexdox. All rights reserved.
// </copyright>
// <summary>
//   Defines the GridRunRepository type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace UnityRepository.Repositories
{
  using System;
  using System.Collections.Generic;
  using System.Data.Entity;
  using System.Data.Entity.Infrastructure;
  using System.Linq;
  using EFRepository;
  using Entities;
  using UnityRepository.Contexts;
  using UnityRepository.Interfaces;

  public class GridRunRepository : BaseEfRepository<GridRun>, IGridRunRepository
  {
    public GridRunRepository(String connectionString)
      : base(new UnityDbContext(connectionString))
    {
    }

    public IList<GridRun> GetProcessing()
    {
      return (from i in this.GetGridsIncludingXmlfileManCoAndDocTypeEntities()
              where i.EndDate == null && i.XmlFile != null
              select i).ToList();
    }

    public IList<GridRun> GetProcessing(List<Int32> manCoIds)
    {
        return (from i in this.GetGridsIncludingXmlfileManCoAndDocTypeEntities()
                where i.EndDate == null && manCoIds.Contains(i.XmlFile.ManCoId)
                select i).ToList();
    }

    public IList<GridRun> GetTopFifteenSuccessfullyCompleted()
    {
      return this.GetGridsIncludingXmlfileManCoAndDocTypeEntities()
              .Where(e => e.EndDate != null && e.Status == 2)
              .OrderByDescending(o => o.Id)
              .Take(15).ToList();
    }

    public IList<GridRun> GetTopFifteenSuccessfullyCompleted(List<Int32> manCoIds)
    {
        return this.GetGridsIncludingXmlfileManCoAndDocTypeEntities()
                .Where(e => (e.EndDate != null && e.Status == 2) && manCoIds.Contains(e.XmlFile.ManCoId))
                .OrderByDescending(o => o.Id)
                .Take(15).ToList();
    }

    public IList<GridRun> GetTopFifteenRecentExceptions()
    {
      return this.GetGridsIncludingXmlfileManCoAndDocTypeEntities()
               .Where(e => e.EndDate != null && (e.Status == 4 || e.Status == 5))
               .OrderByDescending(o => o.Id)
               .Take(15).ToList();
    }

    public IList<GridRun> GetTopFifteenRecentExceptions(List<Int32> manCoIds)
    {
        return this.GetGridsIncludingXmlfileManCoAndDocTypeEntities()
               .Where(e => e.EndDate != null && (e.Status == 4 || e.Status == 5) && manCoIds.Contains(e.XmlFile.ManCoId))
               .OrderByDescending(o => o.Id)
               .Take(15).ToList();
    }

    public IList<GridRun> GetTopFifteenRecentUnapprovedGrids(List<Int32> manCoIds)
    {
      return this.GetGridsIncludingXmlfileManCoAndDocTypeEntities()
        .Where(g =>
          g.Documents.Any(d =>
            d.Approval == null &&
            d.Rejection == null &&
            manCoIds.Contains(d.ManCoId)))
        .OrderByDescending(o => o.Id)
        .Take(15)
        .ToList();
    }

    public IList<GridRun> GetTopFifteenGridsWithRejectedDocuments(List<Int32> manCoIds)
    {
      return this.GetGridsIncludingXmlfileManCoAndDocTypeEntities()
        .Where(g =>
          g.Documents.Any(d =>
            d.Rejection != null &&
            manCoIds.Contains(d.ManCoId)))
        .OrderByDescending(o => o.Id)
        .Take(15)
        .ToList();
    }

    public IList<GridRun> GetTopFifteenGridsAwaitingHouseHolding(List<Int32> manCoIds)
    {
      return this.GetGridsIncludingXmlfileManCoAndDocTypeEntities()
        .Where(g =>
          g.Documents.Any(d =>
            d.HouseHold == null &&
            d.Approval != null &&
            manCoIds.Contains(d.ManCoId)))
        .OrderByDescending(o => o.Id)
        .Take(15)
        .ToList();
    }

    public PagedResult<GridRun> GetGridRuns(Int32 pageNumber, Int32 numberOfItems, String houseHoldingGrid, List<Int32> manCoIds)
    {
      return new PagedResult<GridRun>
               {
                 CurrentPage = pageNumber,
                 ItemsPerPage = numberOfItems,

                 TotalItems =
                   Entities.Count(
                     g => g.HouseHoldingRun.Grid == houseHoldingGrid && manCoIds.Contains(g.Documents.FirstOrDefault().ManCoId)),

                 Results =
                   this.GridsIncludingXmlFileDocTypeAndManCoEntities()
                   .Where(g => g.HouseHoldingRun.Grid == houseHoldingGrid && manCoIds.Contains(g.Documents.FirstOrDefault().ManCoId))
                   .OrderBy(p => p.Id)
                   .Skip((pageNumber - 1) * numberOfItems)
                   .Take(numberOfItems)
                   .ToList()
               };
    }

    public PagedResult<GridRun> GetUnapproved(Int32 pageNumber, Int32 numberOfItems, List<Int32> manCoIds)
    {
     return new PagedResult<GridRun>
                    {
                      CurrentPage = pageNumber,
                      ItemsPerPage = numberOfItems,

                      TotalItems = Entities.Count(g =>
                        g.Documents.Any(d =>
                          d.Approval == null &&
                          d.Rejection == null &&
                          manCoIds.Contains(d.ManCoId))),

                      Results = this.GridsIncludingXmlFileDocTypeAndManCoEntities()
                        .Where(g =>
                          g.Documents.Any(d =>
                            d.Approval == null &&
                            d.Rejection == null &&
                            manCoIds.Contains(d.ManCoId)))
                        .OrderByDescending(p => p.StartDate)
                        .Skip((pageNumber - 1) * numberOfItems)
                        .Take(numberOfItems)
                        .ToList()
                    };
    }

    public GridRun GetGridRun(Int32 id)
    {
      return (from j in this.GridsIncludingXmlfileApprovalRejectionAndHouseholdEntities() 
              where j.Id == id 
              select j).FirstOrDefault();
    }

    public GridRun GetGridRun(String grid)
    {
      return (from g in Entities
              where g.Grid == grid
              select g).FirstOrDefault();
    }

    public GridRun GetGridRun(String code, String grid)
    {
      return (from g in Entities
              where g.Application.Code == code && g.Grid == grid
              select g).FirstOrDefault();
    }

    public GridRun GetGridRun(String fileName, String code, String grid, DateTime startDate)
    {
      return (from g in Entities
              where g.XmlFile.FileName == fileName && g.Application.Code == code && g.Grid == grid && g.StartDate == startDate
              select g).FirstOrDefault();
    }

    public IList<GridRun> Search(String grid)
    {
      return (from g in Entities 
              where g.Grid.Contains(grid) 
              select g).ToList();
    }

    public IList<GridRun> Search(String grid, List<Int32> manCoIds)                                                                                                           
    {
      return (from g in Entities
              where g.Grid.Contains(grid) && manCoIds.Contains(g.XmlFile.ManCoId)
            select g).ToList();
    }

    private IQueryable<GridRun> GetGridsIncludingXmlfileManCoAndDocTypeEntities()
    {
      return Entities.Include(f => f.XmlFile.ManCo).Include(f => f.XmlFile.DocType);
    }

    private IQueryable<GridRun> GridsIncludingXmlfileApprovalRejectionAndHouseholdEntities()
    {
      return Entities
        .Include(f => f.XmlFile)
        .Include(d => d.Documents.Select(a => a.Approval))
        .Include(d => d.Documents.Select(a => a.Rejection))
        .Include(d => d.Documents.Select(h => h.HouseHold));
    }

    private IQueryable<GridRun> GridsIncludingXmlFileDocTypeAndManCoEntities()
    {
      return Entities
        .Include(f => f.XmlFile)
        .Include(f => f.XmlFile.DocType)
        .Include(f => f.XmlFile.ManCo);
    }
  }
}
